package demo;

import java.util.Scanner;

/**
 * @Auther: hjy(lc))
 * @Date: 2022/7/19-07-19-16:44
 * @Description：demo.test
 */
public class testDemo {
    static final long mo = 1000000007;


    public static void main(String[] args) {
        int n, q, x;      //n:数组s的长度，q：操作次数
        long num[] = new long[26];     //存储原数组s中包含字母的数量

        long t = 1;      //统计某字符出现的总次数
        char c;
        String s;        //输入的字符串
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();      //数组长度
        q = sc.nextInt();      //操作次数
        s = sc.next();         //字符串
        for (int i = 0; i < n; i++) {
            c = s.charAt(i);      //获取s中每一位字符
            num[c - 'a']++;       //将字符数量存储进num数组
        }

        for (int i = 0; i < q; i++) {
            x = sc.nextInt();      //x 判断是复制字符串（1）还是统计字符数量（2）
            if (x == 1) {
                x = sc.nextInt();
                //疑惑点：这里为什么要取模 %mo;
                t = t * (x + 1) % mo;     //将字符串s复制x遍拼接到自己末尾，即统计有多少个s

            } else {
                s = sc.next();
                c = s.charAt(0);
                long result = num[c - 'a'] * t % mo;               //对输入的字符c获取到num[]中的值并*s出现的次数t次，再取模
                System.out.println(String.valueOf(result));
            }
        }
    }

}
